package com.wyclabs.mq.eventbus;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * EventBusAutoConfiguration
 * @author Zhang WenTao
 * @version 1.0 create at 2019年8月5日
 */
@ConditionalOnMissingBean(EventManager.class)
public class EventBusAutoConfiguration {

    @Value("amq.topic")
    private String topic;

    @Value("r.tp.%s.event-bus")
    private String uniqueRoutingKeyTemplate;

    @Value("#{'r.tp.${spring.application.name}.event-bus'}")
    private String uniqueRoutingKey;

    @Value("r.tp.shared.event-bus")
    private String sharedRoutingKey;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Bean
    public EventManager eventManager() {
        // @formatter:off
        return new DefaultBusEventManager(
                rabbitTemplate,
                topic,
                uniqueRoutingKey,
                sharedRoutingKey,
                uniqueRoutingKeyTemplate);
        // @formatter:on
    }

    @Bean
    public DefaultBusEventManager.RabbitEventListener rabbitEventListener(DefaultBusEventManager defaultBusEventManager) {
        return defaultBusEventManager.new RabbitEventListener();
    }

    /**
     * RabbitEventBusConfiguration
     * @author Zhang WenTao
     * @version 1.0 create at 2019年8月5日
     */
    @Configuration
    @ConditionalOnClass(RabbitTemplate.class)
    @AutoConfigureAfter({EventBusAutoConfiguration.class, RabbitAutoConfiguration.class})
    protected class RabbitEventBusConfiguration {

        public static final String QUEUE_NAME_EL = "#{'q.t.${spring.application.name}.event-bus'}";

        @Bean("amqTopic")
        public TopicExchange amqTopic() {
            return new TopicExchange(topic, true, false);
        }

        @Bean("eventBusQueue")
        public Queue eventBusQueue(@Value(QUEUE_NAME_EL) String name) {
            return new Queue(name);
        }

        @Bean
        public Binding eventBusSharedBinding(@Qualifier("eventBusQueue") Queue eventBusQueue,
                                             @Qualifier("amqTopic") TopicExchange amqTopic) {
            // @formatter:off
            return BindingBuilder.bind(eventBusQueue)
                    .to(amqTopic)
                    .with(sharedRoutingKey);
            // @formatter:on
        }

        @Bean
        public Binding eventBusUniqueBinding(@Qualifier("eventBusQueue") Queue eventBusQueue,
                                             @Qualifier("amqTopic") TopicExchange amqTopic) {
            // @formatter:off
            return BindingBuilder.bind(eventBusQueue)
                    .to(amqTopic)
                    .with(uniqueRoutingKey);
            // @formatter:on
        }

    }

}
